package com.spark.common.helper

import android.graphics.Canvas
import android.graphics.Rect
import android.support.v7.widget.GridLayoutManager
import android.support.v7.widget.RecyclerView
import android.support.v7.widget.StaggeredGridLayoutManager
import android.view.View
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable
import android.support.v7.widget.LinearLayoutManager
import com.blankj.utilcode.util.LogUtils


/**
 * ItemDecoration <><><>Don't waste
 */
open class SpacesItemDecoration(private var leftRight: Int, private var topBottom: Int, private var width: Int = 0, private var height: Int = 0, private var mColor: Int) : RecyclerView.ItemDecoration() {

    private var mEntrust: SpacesItemDecorationEntrust? = null


    override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
        if (mEntrust == null) {
            mEntrust = getEntrust(parent.layoutManager)
        }
        mEntrust!!.onDraw(c, parent, state)
        super.onDraw(c, parent, state)
    }

    override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
        if (mEntrust == null) {
            mEntrust = getEntrust(parent.layoutManager)
        }
        mEntrust!!.getItemOffsets(outRect, view, parent, state)
    }

    private fun getEntrust(manager: RecyclerView.LayoutManager): SpacesItemDecorationEntrust {
        var entrust: SpacesItemDecorationEntrust? = null
        //要注意这边的GridLayoutManager是继承LinearLayoutManager，所以要先判断GridLayoutManager
        entrust = when (manager) {
            is GridLayoutManager -> GridEntrust(leftRight, topBottom, width, height, mColor)
            is StaggeredGridLayoutManager -> StaggeredGridEntrust(leftRight, topBottom, width, height, mColor)
            else -> //其他的都当做Linear来进行计算
                LinearEntrust(leftRight, topBottom, width, height, mColor)
        }
        return entrust
    }
}

/**
 * @leftRight: 分割线的宽度
 * @topBottom: 分割线的高度
 * @width: 大于-1  以该值为准
 * @heiht: 大于-1 以该值为准
 *
 */
abstract class SpacesItemDecorationEntrust(protected var leftRight: Int, protected var topBottom: Int, protected var width: Int = 0, protected var height: Int = 0, mColor: Int) {

    //color的传入方式是resouce.getcolor
    protected var mDivider: Drawable? = null

    init {
        if (mColor != 0) {
            mDivider = ColorDrawable(mColor)
        }
    }

    internal abstract fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State)

    internal abstract fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State)

}

/**
 * Linear >>>>>>>>
 */
class LinearEntrust(leftRight: Int, topBottom: Int, width: Int, height: Int, mColor: Int) : SpacesItemDecorationEntrust(leftRight, topBottom, width, height, mColor) {

    override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
        val layoutManager = parent.layoutManager as LinearLayoutManager
        //没有子view或者没有没有颜色直接return
        if (mDivider == null || layoutManager.childCount === 0) {
            return
        }
        var left: Int
        var right: Int
        var top: Int
        var bottom: Int
        val childCount = parent.childCount
        if (layoutManager.orientation === GridLayoutManager.VERTICAL) {
            for (i in 0 until childCount - 1) {
                val child = parent.getChildAt(i)
                val params = child.layoutParams as RecyclerView.LayoutParams
                //将有颜色的分割线处于中间位置
                val center = (layoutManager.getTopDecorationHeight(child) + 1 - topBottom) / 2
                //计算下边的
                left = layoutManager.getLeftDecorationWidth(child)
                right = parent.width - layoutManager.getLeftDecorationWidth(child)
                top = (child.bottom + center).toInt()
                bottom = top + topBottom
                mDivider!!.setBounds(left, top, right, bottom)
                mDivider!!.draw(c)
            }
        } else {
            for (i in 0 until childCount - 1) {
                val child = parent.getChildAt(i)
                val params = child.layoutParams as RecyclerView.LayoutParams
                //将有颜色的分割线处于中间位置
                val center = (layoutManager.getLeftDecorationWidth(child) + 1 - leftRight) / 2
                //计算右边的
                left = (child.right + center).toInt()
                right = left + leftRight
                top = layoutManager.getTopDecorationHeight(child)
                bottom = parent.height - layoutManager.getTopDecorationHeight(child)
                mDivider!!.setBounds(left, top, right, bottom)
                mDivider!!.draw(c)
            }
        }

    }

    override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
        val layoutManager = parent.layoutManager as LinearLayoutManager
        //竖直方向的
        if (layoutManager.getOrientation() === LinearLayoutManager.VERTICAL) {
            //最后一项需要 bottom
            if (parent.getChildAdapterPosition(view) == layoutManager.getItemCount() - 1) {
                outRect.bottom = topBottom
            }
            outRect.top = topBottom
            outRect.left = leftRight
            outRect.right = leftRight
        } else {
            //最后一项需要right
            if (parent.getChildAdapterPosition(view) == layoutManager.getItemCount() - 1) {
                outRect.right = leftRight
            }
            outRect.top = topBottom
            outRect.left = leftRight
            outRect.bottom = topBottom
        }
    }
}

/**
 * Grid >>>>>>>>>
 */
class GridEntrust(leftRight: Int, topBottom: Int, width: Int, height: Int, mColor: Int) : SpacesItemDecorationEntrust(leftRight, topBottom, width, height, mColor) {

    override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
        val layoutManager = parent.layoutManager as GridLayoutManager
        val lookup = layoutManager.spanSizeLookup

        if (mDivider == null || layoutManager.childCount == 0) {
            return
        }
        //判断总的数量是否可以整除
        val spanCount = layoutManager.spanCount
        var left: Int
        var right: Int
        var top: Int
        var bottom: Int
        val childCount = parent.childCount
        if (layoutManager.orientation == GridLayoutManager.VERTICAL) {
            for (i in 0 until childCount) {
                val child = parent.getChildAt(i)
                //将带有颜色的分割线处于中间位置
                val centerLeft = ((layoutManager.getLeftDecorationWidth(child) + layoutManager.getRightDecorationWidth(child)).toFloat() * spanCount / (spanCount + 1) + 1 - leftRight) / 2
                val centerTop = ((layoutManager.getBottomDecorationHeight(child) + 1 - topBottom) / 2).toFloat()
                //得到它在总数里面的位置
                val position = parent.getChildAdapterPosition(child)
                //获取它所占有的比重
                val spanSize = lookup.getSpanSize(position)
                //获取每排的位置
                val spanIndex = lookup.getSpanIndex(position, layoutManager.spanCount)
                //判断是否为第一排
                val isFirst = layoutManager.spanSizeLookup.getSpanGroupIndex(position, spanCount) == 0
                //画上边的，第一排不需要上边的,只需要在最左边的那项的时候画一次就好
                if (!isFirst && spanIndex == 0) {
                    left = layoutManager.getLeftDecorationWidth(child)
                    right = parent.width - layoutManager.getLeftDecorationWidth(child)
                    top = (child.top - centerTop).toInt() - topBottom
                    bottom = top + topBottom
                    LogUtils.e("divider >>> leftRight = $leftRight topBottom = $topBottom left = $left top = $top right = $right bottom = $bottom")
                    handleDraw(left, top, c)
                }
                //最右边的一排不需要右边的
                val isRight = spanIndex + spanSize == spanCount
                if (!isRight) {
                    //计算右边的
                    left = (child.right + centerLeft).toInt()
                    right = left + leftRight
                    top = child.top
                    if (!isFirst) {
                        top -= centerTop.toInt()
                    }
                    bottom = (child.bottom + centerTop).toInt()
                    handleDraw(left, top, c)
                }
            }
        } else {
            for (i in 0 until childCount) {
                val child = parent.getChildAt(i)
                //将带有颜色的分割线处于中间位置
                val centerLeft = ((layoutManager.getRightDecorationWidth(child) + 1 - leftRight) / 2).toFloat()
                val centerTop = ((layoutManager.getTopDecorationHeight(child) + layoutManager.getBottomDecorationHeight(child)).toFloat() * spanCount / (spanCount + 1) - topBottom) / 2
                //得到它在总数里面的位置
                val position = parent.getChildAdapterPosition(child)
                //获取它所占有的比重
                val spanSize = lookup.getSpanSize(position)
                //获取每排的位置
                val spanIndex = lookup.getSpanIndex(position, layoutManager.spanCount)
                //判断是否为第一列
                val isFirst = layoutManager.spanSizeLookup.getSpanGroupIndex(position, spanCount) == 0
                //画左边的，第一排不需要左边的,只需要在最上边的那项的时候画一次就好
                if (!isFirst && spanIndex == 0) {
                    left = (child.left - centerLeft).toInt() - leftRight
                    right = left + leftRight
                    top = layoutManager.getRightDecorationWidth(child)
                    bottom = parent.height - layoutManager.getTopDecorationHeight(child)
                    handleDraw(left, top, c)
                }
                //最下的一排不需要下边的
                val isRight = spanIndex + spanSize == spanCount
                if (!isRight) {
                    //计算右边的
                    left = child.left
                    if (!isFirst) {
                        left -= centerLeft.toInt()
                    }
                    right = (child.right + centerTop).toInt()
                    top = (child.bottom + centerLeft).toInt()
                    bottom = top + leftRight
                    handleDraw(left, top, c)
                }
            }
        }
    }

    private fun handleDraw(left: Int, top: Int, c: Canvas) {
        var centerX = left + width / 2
        var centerY = top + height / 2
        var startX = centerX - width / 2
        var startY = centerY - height / 2
        var endX = centerX + width / 2
        var enY = centerY + height / 2
        mDivider!!.setBounds(startX, startY, endX, enY)
        //mDivider!!.setBounds(left, top, right, bottom)
        mDivider!!.draw(c)
    }

    override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
        val layoutManager = parent.layoutManager as GridLayoutManager
        val lp = view.layoutParams as GridLayoutManager.LayoutParams
        val childPosition = parent.getChildAdapterPosition(view)
        val spanCount = layoutManager.spanCount

        if (layoutManager.orientation == GridLayoutManager.VERTICAL) {
            //判断是否在第一排
            if (layoutManager.spanSizeLookup.getSpanGroupIndex(childPosition, spanCount) == 0) {//第一排的需要上面
                outRect.top = topBottom
            }
            outRect.bottom = topBottom
            //这里忽略和合并项的问题，只考虑占满和单一的问题
            if (lp.spanSize == spanCount) {//占满
                outRect.left = leftRight
                outRect.right = leftRight
            } else {
                outRect.left = ((spanCount - lp.spanIndex).toFloat() / spanCount * leftRight).toInt()
                outRect.right = (leftRight.toFloat() * (spanCount + 1) / spanCount - outRect.left).toInt()
            }
        } else {
            if (layoutManager.spanSizeLookup.getSpanGroupIndex(childPosition, spanCount) == 0) {//第一排的需要left
                outRect.left = leftRight
            }
            outRect.right = leftRight
            //这里忽略和合并项的问题，只考虑占满和单一的问题
            if (lp.spanSize == spanCount) {//占满
                outRect.top = topBottom
                outRect.bottom = topBottom
            } else {
                outRect.top = ((spanCount - lp.spanIndex).toFloat() / spanCount * topBottom).toInt()
                outRect.bottom = (topBottom.toFloat() * (spanCount + 1) / spanCount - outRect.top).toInt()
            }
        }
    }


}

/**
 * StaggeredGrid >>>>>>>>
 */
class StaggeredGridEntrust(leftRight: Int, topBottom: Int, width: Int, height: Int, mColor: Int) : SpacesItemDecorationEntrust(leftRight, topBottom, width, height, mColor) {
    internal override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
        // 因为排列的不确定性，暂时没找到比较好的处理方式
        //        StaggeredGridLayoutManager layoutManager = (StaggeredGridLayoutManager) parent.getLayoutManager();
        //        if (mDivider == null || layoutManager.getChildCount() == 0) {
        //            return;
        //        }
        //        int left;
        //        int ic_arrow_right_blue;
        //        int top;
        //        int bottom;
        //
        //        final int spanCount = layoutManager.getSpanCount();
        //        final int childCount = parent.getChildCount();
        //
        //        //获取最后显示的几项
        //        int[] intos = new int[spanCount];
        //        layoutManager.findLastVisibleItemPositions(intos);
        //
        //        //换个思路，每个item都画边和右边，当然第一排的不需要上边，最右边的不需要右边
        //        if (layoutManager.getOrientation() == StaggeredGridLayoutManager.VERTICAL) {
        //            for (int i = 0; i < childCount; i++) {
        //                final View child = parent.getChildAt(i);
        //                final StaggeredGridLayoutManager.LayoutParams params = (StaggeredGridLayoutManager.LayoutParams) child.getLayoutParams();
        //                //得到它在总数里面的位置
        //                final int position = parent.getChildAdapterPosition(child);
        //                //它在每列的位置
        //                final int spanPosition = params.getSpanIndex();
        //                //将带有颜色的分割线处于中间位置
        //                final float centerLeft = (layoutManager.getLeftDecorationWidth(child) + 1 - leftRight) / 2;
        //                final float centerTop = (layoutManager.getBottomDecorationHeight(child) + 1 - topBottom) / 2;
        //                //画上边的
        //                if (position > spanCount - 1) {
        //                    left = child.getLeft() + params.leftMargin;
        //                    if (spanPosition > 0) {
        //                        left -= centerLeft;
        //                    }
        //                    ic_arrow_right_blue = child.getRight() + params.rightMargin;
        //                    if (spanPosition + 1 != spanCount) {//最右边的不需要那一丢丢
        //                        ic_arrow_right_blue += centerLeft;
        //                    }
        //                    top = (int) (child.getTop() + params.topMargin - centerTop - topBottom);
        //                    bottom = top + topBottom;
        //                    mDivider.setBounds(left, top, ic_arrow_right_blue, bottom);
        //                    mDivider.draw(c);
        //                }
        //                //画右边的
        //                if ((spanPosition + 1) % spanCount != 0) {
        //                    left = (int) (child.getRight() + params.rightMargin + centerLeft);
        //                    ic_arrow_right_blue = left + leftRight;
        //                    top = child.getTop() + params.topMargin;
        //                    //第一排的不需要上面那一丢丢
        //                    if (position > spanCount - 1) {//换个思路，都给top了
        //                        top -= centerTop + centerTop + topBottom;
        //                    }
        //                    bottom = child.getBottom() + params.bottomMargin;
        //                    mDivider.setBounds(left, top, ic_arrow_right_blue, bottom);
        //                    mDivider.draw(c);
        //                }
        //            }
        //
        //        } else {
        //            for (int i = 0; i < childCount; i++) {
        //                final View child = parent.getChildAt(i);
        //                final StaggeredGridLayoutManager.LayoutParams params = (StaggeredGridLayoutManager.LayoutParams) child.getLayoutParams();
        //                //得到它在总数里面的位置
        //                final int position = parent.getChildAdapterPosition(child);
        //                //它在每列的位置
        //                final int spanPosition = params.getSpanIndex();
        //                //将带有颜色的分割线处于中间位置
        //                final float centerLeft = (layoutManager.getRightDecorationWidth(child) + 1 - leftRight) / 2;
        //                final float centerTop = (layoutManager.getTopDecorationHeight(child) + 1 - topBottom) / 2;
        //                //画左边
        //                if (position > spanCount - 1) {
        //                    left = (int) (child.getLeft() + params.leftMargin - centerLeft - leftRight);
        //                    ic_arrow_right_blue = left + leftRight;
        //                    top = (int) (child.getTop() + params.topMargin - centerTop);
        //                    if (spanPosition == 0) {
        //                        top += centerTop;
        //                    }
        //                    bottom = child.getBottom() + params.bottomMargin;
        //                    if (spanPosition + 1 != spanCount) {
        //                        bottom += centerTop;
        //                    }
        //                    mDivider.setBounds(left, top, ic_arrow_right_blue, bottom);
        //                    mDivider.draw(c);
        //                }
        //                //画上面的
        //                if (spanPosition > 0) {
        //                    left = child.getLeft() + params.leftMargin;
        //                    if (position > spanCount - 1) {//换个思路，都给left了
        //                        left -= centerLeft + centerLeft + leftRight;
        //                    }
        //                    ic_arrow_right_blue = child.getRight() + params.rightMargin;
        //                    top = (int) (child.getTop() + params.bottomMargin - centerTop - topBottom);
        //                    bottom = top + topBottom;
        //                    mDivider.setBounds(left, top, ic_arrow_right_blue, bottom);
        //                    mDivider.draw(c);
        //                }
        //            }
        //        }
    }

    internal override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
        val layoutManager = parent.layoutManager as StaggeredGridLayoutManager
        val lp = view.layoutParams as StaggeredGridLayoutManager.LayoutParams
        val childPosition = parent.getChildAdapterPosition(view)
        val spanCount = layoutManager.spanCount
        val spanSize = if (lp.isFullSpan) layoutManager.spanCount else 1

        if (layoutManager.orientation == GridLayoutManager.VERTICAL) {
            if (getSpanGroupIndex(childPosition, spanCount, spanSize) == 0) {//第一排的需要上面
                outRect.top = topBottom
            }
            outRect.bottom = topBottom
            //这里忽略和合并项的问题，只考虑占满和单一的问题
            if (lp.isFullSpan) {//占满
                outRect.left = leftRight
                outRect.right = leftRight
            } else {
                outRect.left = ((spanCount - lp.spanIndex).toFloat() / spanCount * leftRight).toInt()
                outRect.right = (leftRight.toFloat() * (spanCount + 1) / spanCount - outRect.left).toInt()
            }
        } else {
            if (getSpanGroupIndex(childPosition, spanCount, spanSize) == 0) {//第一排的需要left
                outRect.left = leftRight
            }
            outRect.right = leftRight
            //这里忽略和合并项的问题，只考虑占满和单一的问题
            if (lp.isFullSpan) {//占满
                outRect.top = topBottom
                outRect.bottom = topBottom
            } else {
                outRect.top = ((spanCount - lp.spanIndex).toFloat() / spanCount * topBottom).toInt()
                outRect.bottom = (topBottom.toFloat() * (spanCount + 1) / spanCount - outRect.top).toInt()
            }
        }
    }

    fun getSpanGroupIndex(adapterPosition: Int, spanCount: Int, spanSize: Int): Int {
        var span = 0
        var group = 0
        for (i in 0 until adapterPosition) {
            span += spanSize
            if (span == spanCount) {
                span = 0
                group++
            } else if (span > spanCount) {
                // did not fit, moving to next row / column
                span = spanSize
                group++
            }
        }
        if (span + spanSize > spanCount) {
            group++
        }
        return group
    }
}